package com.dhecp.project.storage.service.impl;

import com.alibaba.fastjson.JSON;
import com.dhecp.common.core.domain.AjaxResult;
import com.dhecp.common.utils.MessageUtils;
import com.dhecp.common.utils.RandomValueUtils;
import com.dhecp.common.utils.TypeUtils;
import com.dhecp.core.constant.DataFiltering;
import com.dhecp.core.utils.PageUtils;
import com.dhecp.core.utils.ReflectUtils;
import com.dhecp.project.common.domain.ModuleNID;
import com.dhecp.project.common.domain.RecordCheck;
import com.dhecp.project.common.domain.UpdateDeleted;
import com.dhecp.project.common.domain.UpdateFlow;
import com.dhecp.project.common.service.UpdateLogService;
import com.dhecp.project.common.service.impl.BaseModuleServiceImpl;
import com.dhecp.project.purchase.domain.PurchasePlan;
import com.dhecp.project.purchase.domain.Refund;
import com.dhecp.project.storage.domain.Dismounting;
import com.dhecp.project.storage.domain.StockControl;
import com.dhecp.project.storage.mapper.DismountingMapper;
import com.dhecp.project.storage.mapper.StockControlMapper;
import com.dhecp.project.storage.service.DismountingService;
import com.dhecp.project.system.service.SysDictionaryForFieldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: kjecp
 * @description: 仓储 拆装单
 * @author: hlf
 * @create: 2022-09-01 15:43
 */
@Service
public class DismountingServiceImpl extends BaseModuleServiceImpl implements DismountingService {


    @Autowired
    private DismountingMapper storageMapper;
    @Autowired
    private UpdateLogService updateLogService;
    @Autowired
    private StockControlMapper stockControlMapper;

    @Autowired
    private SysDictionaryForFieldService dictionaryForFieldService;

    /**
     * @Description: 查询前一单NID、BID
     * @Param: [params] nid 必要参数：当前 单据编码
     * @return: com.dhecp.common.core.domain.AjaxResult  (data.nid 前一单NID， data.bid 前一单BID)
     * @Author: hlf
     * @date: 2022-05-09 10:08
     */
    @Override
    public AjaxResult queryLastNid(Map<String, Object> params) throws Exception {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        if (params.get("nid") == null || params.get("nid") == "") {
            params.put("nid", "0");
        }
        params.put(DataFiltering.TABLE_ALIAS, "t1");    //查询表别名
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));    //数据权限查询条件SQL语句
        ModuleNID moduleNID = storageMapper.selectLastNid(params);
        if (moduleNID == null) {
            dataMap.put("nid", "0");
            dataMap.put("bid", "0");
            return AjaxResult.warn(MessageUtils.message("module.warn.isfirstnid"), TypeUtils.mapToJson(dataMap).toString());
        }
        dataMap.put("nid", moduleNID.getNid().toString());
        dataMap.put("bid", moduleNID.getBid().toString());
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), TypeUtils.mapToJson(dataMap).toString());
    }


    /**
     * @Description: 查询后一单NID、BID
     * @Param: [params] nid 必要参数：当前 单据编码
     * @return: com.dhecp.common.core.domain.AjaxResult  (data.nid 后一单NID， data.bid 后一单BID)
     * @Author: hlf
     * @date: 2022-05-09 10:09
     */
    @Override
    public AjaxResult queryNextNid(Map<String, Object> params) throws Exception {
        Map<String, Object> dataMap = new HashMap<String, Object>();
        if (params.get("nid") == null || params.get("nid") == "" || "0".equals(params.get("nid").toString())) {
            dataMap.put("nid", "0");
            dataMap.put("bid", "0");
            return AjaxResult.warn(MessageUtils.message("module.warn.isfinallynid"), TypeUtils.mapToJson(dataMap).toString());
        }
        params.put(DataFiltering.TABLE_ALIAS, "t1");    //查询表别名
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));    //数据权限查询条件SQL语句
        ModuleNID moduleNID = storageMapper.selectNextNid(params);
        if (moduleNID == null) {
            dataMap.put("nid", "0");
            dataMap.put("bid", "0");
            return AjaxResult.warn(MessageUtils.message("module.warn.isfinallynid"), TypeUtils.mapToJson(dataMap).toString());
        }
        dataMap.put("nid", moduleNID.getNid().toString());
        dataMap.put("bid", moduleNID.getBid().toString());
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), TypeUtils.mapToJson(dataMap).toString());
    }


    /**
     * @Description: 查询指定单nid的首记录
     * @Param: [params]
     * @return: com.dhecp.project.storage.domain.Dismounting
     * @Author: hlf
     * @date: 2022-05-09 10:10
     */
    @Override
    public Dismounting queryFirstRecord(Map<String, Object> params) throws Exception {
        params.put(DataFiltering.TABLE_ALIAS, "t1");    //查询表别名
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));    //数据权限查询条件SQL语句
        return storageMapper.selectFirstRecordByNid(params);
    }

    /**
     * @Description: 查询指定单nid的整单录
     * @Param: [params] nid 必要参数：当前 单据编码
     * @return: java.util.List<com.dhecp.project.storage.domain.Dismounting>
     * @Author: hlf
     * @date: 2022-05-09 10:10
     */
    @Override
    public List<Dismounting> queryListByNid(Map<String, Object> params) throws Exception {
        params.put(DataFiltering.TABLE_ALIAS, "t1");    //查询表别名
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));    //数据权限查询条件SQL语句
        return storageMapper.selectByNid(params);
    }


    /**
     * @Description: 查询
     * @Param: [params]
     * @return: java.util.List<com.dhecp.project.storage.domain.Dismounting>
     * @Author: hlf
     * @date: 2022-05-09 10:10
     */
    @Override
    public List<Dismounting> queryList(Map<String, Object> params) throws Exception {
        params.put(DataFiltering.TABLE_ALIAS, "t1");    //查询表别名
        params.put(DataFiltering.DATA_WHERE, dictionaryForFieldService.getWhereStr(params));    //常规查询条件SQL语句
        params.put(DataFiltering.DATA_SCODE, dictionaryForFieldService.getDataScode(params));    //数据权限查询条件SQL语句
        PageUtils.startPageStronger();
        return storageMapper.select(params);
    }

    /**
     * @Description: 保存
     * @Param: [params] moduleTable 必要参数：功能唯一标识
     * @Param: [params] infoMap 必要参数：非网格字段（包括头部、底部所有显示和隐藏的字段）
     * @Param: [params] infoItems 必要参数：对应实体类的json格式字符串
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-05-09 10:10
     */
    @SuppressWarnings("unchecked")
    @Override
    @Transactional(timeout = 300, propagation = Propagation.REQUIRES_NEW)//事务回滚
    public AjaxResult saveData(Map<String, Object> params) {
        params.put("businessEntity", new Dismounting());
        boolean isUpdateStock = true;
        Dismounting oldData;

        Dismounting onData = JSON.parseObject(params.get("infoMap").toString(), Dismounting.class);
        if (onData.getDestuffingNum() > onData.getStockNum()) {
            return AjaxResult.error("拆装数量，不可大于库存数量");
        }
        AjaxResult ajaxResult = this.saveDataBase(params);
        if (!"0".equals(ajaxResult.get("code").toString())) {
            throw new RuntimeException(ajaxResult.get("msg").toString());
        }

        String resNid = "0";
        Map<String, Object> infoMap = (Map<String, Object>) ajaxResult.get("infoMap");
        List<Dismounting> businessDataList = (List<Dismounting>) ajaxResult.get("businessDataList");


        List<RecordCheck> guidMapList = storageMapper.findRecords(infoMap.get("nid").toString());
        Map<String, Object> guidMap = new HashMap<String, Object>();
        if (!guidMapList.isEmpty()) {
            if (infoMap.get("newNid") != null && "1".equals(infoMap.get("newNid").toString())) { //单号重复验证
                throw new RuntimeException(MessageUtils.message("module.error.retry"));
            }
            for (RecordCheck recordCheck : guidMapList) {
                if (recordCheck != null && recordCheck.getGuid() != null) {
                    guidMap.put(recordCheck.getGuid().toString(), "1");
                }
            }
        }


        if (businessDataList == null || businessDataList.size() == 0) {
            resNid = "0";
            //删除的情况下
            //解冻库存
            Map<String, Object> params2 = new HashMap<String, Object>();
            params2.put("nid", onData.getNid());
            oldData = storageMapper.selectFirstRecordByNid(params2);
            StockControl stockControl = getStockControl(oldData);
            if (stockControl != null) {
                stockControl.setProductNum(stockControl.getProductNum() + oldData.getDestuffingNum());
                stockControlMapper.update(stockControl);
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//事务回滚
                return AjaxResult.error("库存失效!");
            }
        } else {
            resNid = infoMap.get("nid").toString();
            for (Dismounting businessData : businessDataList) {
                String guid = "";
                if (businessData.getGuid() == null) {
                    guid = RandomValueUtils.getGUID();
                } else {
                    guid = businessData.getGuid().toString();
                }
                businessData.setGuid(guid);
                for (String field : infoMap.keySet()) { //遍历非网格字段，并赋值到实体中
                    Object fieldValue = infoMap.get(field);
                    ReflectUtils.setValue(businessData, field, fieldValue);
                }

                if (guidMap.get(guid) == null) {
                    businessData.setCreateTime(new Date());
                    storageMapper.insert(businessData);
                    //冻结库存
                    if (isUpdateStock) {
                        StockControl stockControl = getStockControl(businessData);
                        if (stockControl != null && (stockControl.getProductNum() >= businessData.getDestuffingNum())) {
                            stockControl.setProductNum(stockControl.getProductNum() - businessData.getDestuffingNum());
                            stockControlMapper.update(stockControl);
                            isUpdateStock = false;
                        } else {
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//事务回滚
                            return AjaxResult.error("可用库存不足!");
                        }

                    }
                    updateLogService.addInsertLog(params.get("moduleTable").toString(), guid, "新增");
                } else {
                    Map<String, Object> params2 = new HashMap<String, Object>();
                    params2.put("guid", guid);
                    oldData = storageMapper.findById(params2);
                    storageMapper.update(businessData);

                    //修改冻结库存
                    if (isUpdateStock) {
                        //先解冻在冻结
                        //解冻库存
                        StockControl stockControl = getStockControl(businessData);
                        if (stockControl != null && (stockControl.getProductNum() >= businessData.getDestuffingNum())) {
                            stockControl.setProductNum(stockControl.getProductNum() + oldData.getDestuffingNum() - businessData.getDestuffingNum());
                            stockControlMapper.update(stockControl);
                            isUpdateStock = false;
                        } else {
                            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//事务回滚
                            return AjaxResult.error("可用库存不足!");
                        }
                    }
                    updateLogService.addUpdateLog(params.get("moduleTable").toString(), guid, oldData, businessData, "修改");
                    guidMap.remove(guid);
                }

            }
        }

        if (!guidMap.isEmpty()) {
            for (String guid : guidMap.keySet()) {
                storageMapper.delete(guid);
            }
        }
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), resNid);
    }

    /**
     * @Description: 删除
     * @Param: [params]
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-05-09 10:11
     */
    @Override
    @Transactional(timeout = 300, propagation = Propagation.REQUIRES_NEW)//事务回滚
    public AjaxResult deleteData(Map<String, Object> params) {
        List<Dismounting> businessDataList = JSON.parseArray(params.get("infoItems").toString(), Dismounting.class);
        if (businessDataList == null || businessDataList.size() == 0) {
            return AjaxResult.error(MessageUtils.message("module.error.jsontoentyerror"));
        }
        boolean isUpdateStock = true;
        for (Dismounting businessData : businessDataList) {
            storageMapper.delete(businessData);
            //修改冻结库存
            if (isUpdateStock) {
                //解冻库存
                StockControl stockControl = getStockControl(businessData);
                if (stockControl != null) {
                    stockControl.setProductNum(stockControl.getProductNum() + businessData.getDestuffingNum());
                    stockControlMapper.update(stockControl);
                    isUpdateStock = false;
                } else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//事务回滚
                    return AjaxResult.error("库存失效!");
                }
            }
        }
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    /**
     * @Description: 修改删除标志（预留）
     * @Param: [params] infoItems 必要参数：对应实体类的json格式字符串（仅需 guid 和 deleted）
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-05-09 10:11
     */
    @Override
    public AjaxResult updateDeleted(Map<String, Object> params) {
        List<UpdateDeleted> updateDeletedList = JSON.parseArray(params.get("infoItems").toString(), UpdateDeleted.class);
        if (updateDeletedList == null || updateDeletedList.size() == 0) {
            return AjaxResult.error(MessageUtils.message("module.error.jsontoentyerror"));
        }
        for (UpdateDeleted updateDeleted : updateDeletedList) {
            storageMapper.updateDeleted(updateDeleted);
        }
        return AjaxResult.success(MessageUtils.message("module.success.issuccess"));
    }

    /**
     * @Description: 流转  —— 添加流程任务、修改流程状态及生效标志
     * @Param: [params] tableDataId 必要参数：单据编码（nid）
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-05-09 10:11
     */
    @Override
    @Transactional(timeout = 300, propagation = Propagation.REQUIRES_NEW)//事务回滚
    public AjaxResult updateFlowGo(Map<String, Object> params) {
        Map<String, Object> infoMap = new HashMap<String, Object>();
        String nid = "0";
        if (params.get("tableDataId") == null || params.get("tableDataId") == "") {
            return AjaxResult.error(MessageUtils.message("module.error.lack", "单据编码【tableDataId】"));
        } else {
            nid = params.get("tableDataId").toString();
        }
        params.put("nid", nid);
        List<Dismounting> businessDataList = storageMapper.selectByNid(params);
        if (businessDataList == null || businessDataList.size() == 0) {
            return AjaxResult.error(MessageUtils.message("module.error.nodata"));
        } else {
            infoMap.put("cid", businessDataList.get(0).getCid());
            infoMap.put("bUser", businessDataList.get(0).getbUser());
            infoMap.put("bDept", businessDataList.get(0).getbDept());
            infoMap.put("procInstId", businessDataList.get(0).getProcInstId());
            infoMap.put("activeFlow", businessDataList.get(0).getActiveFlow());
            infoMap.put("createTime", businessDataList.get(0).getCreateTime());
            params.put("infoMap", TypeUtils.mapToJson(infoMap).toString());
            params.put("activeFlowOld", businessDataList.get(0).getActiveFlow());
        }

        //流程处理公共方法，返回单据（流转、回退等）后的流程状态信息
        if (params.get("optType") == null || params.get("optType") == "") {
            params.put("optType", "go");
        }
        UpdateFlow updateFlow = new UpdateFlow();
        updateFlow = this.FlowDealBase(params);

        if (updateFlow.getActiveFlow().equals("end")) {//当流程结束时
            //需要拆掉母件库存 并且加装子件库存
            //查询库存数据
            StockControl stockControl = getStockControl(businessDataList.get(0));
            if (stockControl != null) {
                stockControl.setProductNumAll(stockControl.getProductNumAll() - businessDataList.get(0).getDestuffingNum());
                stockControlMapper.update(stockControl);//处理母件
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//事务回滚
                return AjaxResult.error("库存无效!");
            }
            // 拆分子件
            for (Dismounting item : businessDataList
            ) {
                StockControl newStock = getStockControlZj(item);
                if (newStock != null) {//不为空时 修改库存
                    newStock.setProductNum(newStock.getProductNum() + item.getDestuffingNum());
                    newStock.setProductNumAll(newStock.getProductNumAll() + item.getDestuffingNum());
                    stockControlMapper.update(newStock);
                } else {//否则新增
                    addStockControl(item);
                }
            }
        }


        for (Dismounting businessData : businessDataList) {
            updateFlow.setGuid(businessData.getGuid());
            storageMapper.updateFlow(updateFlow);
        }

        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), nid);
    }

    /**
     * @Description: 退回  —— 添加流程任务、修改流程状态及生效标志
     * @Param: [params] tableDataId 必要参数：单据编码（nid）
     * @return: com.dhecp.common.core.domain.AjaxResult
     * @Author: hlf
     * @date: 2022-05-09 10:11
     */
    @Override
    @Transactional(timeout = 300, propagation = Propagation.REQUIRES_NEW)//事务回滚
    public AjaxResult updateFlowBack(Map<String, Object> params) {
        Map<String, Object> infoMap = new HashMap<String, Object>();
        String nid = "0";
        if (params.get("tableDataId") == null || params.get("tableDataId") == "") {
            return AjaxResult.error(MessageUtils.message("module.error.lack", "单据编码【tableDataId】"));
        } else {
            nid = params.get("tableDataId").toString();
        }
        params.put("nid", nid);
        List<Dismounting> businessDataList = storageMapper.selectByNid(params);
        if (businessDataList == null || businessDataList.size() == 0) {
            return AjaxResult.error(MessageUtils.message("module.error.nodata"));
        } else {
            infoMap.put("cid", businessDataList.get(0).getCid());
            infoMap.put("bUser", businessDataList.get(0).getbUser());
            infoMap.put("bDept", businessDataList.get(0).getbDept());
            infoMap.put("procInstId", businessDataList.get(0).getProcInstId());
            infoMap.put("activeFlow", businessDataList.get(0).getActiveFlow());
            infoMap.put("createTime", businessDataList.get(0).getCreateTime());
            params.put("infoMap", TypeUtils.mapToJson(infoMap).toString());
            params.put("activeFlowOld", businessDataList.get(0).getActiveFlow());
        }

        //流程处理公共方法，返回单据（流转、回退等）后的流程状态信息
        if (params.get("optType") == null || params.get("optType") == "") {
            params.put("optType", "back");
        }
        UpdateFlow updateFlow = new UpdateFlow();
        updateFlow = this.FlowDealBase(params);

        if (businessDataList.get(0).getEffectStock() && !updateFlow.getEffectStock()) { //当流程重置时
            //需要删掉子件库存 并且加回母件库存
            StockControl stockControl = getStockControl(businessDataList.get(0));
            if (stockControl != null) {
                stockControl.setProductNum(stockControl.getProductNum() + businessDataList.get(0).getDestuffingNum());
                stockControl.setProductNumAll(stockControl.getProductNumAll() + businessDataList.get(0).getDestuffingNum());
                stockControlMapper.update(stockControl);//处理母件
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//事务回滚
                return AjaxResult.error("库存无效!");
            }
            // 拆分子件
            for (Dismounting item : businessDataList
            ) {
                StockControl newStock = getStockControlZj(item);
                if (newStock != null) {//不为空时 修改库存
                    newStock.setProductNum(newStock.getProductNum() - item.getDestuffingNum());
                    newStock.setProductNumAll(newStock.getProductNumAll() - item.getDestuffingNum());
                    stockControlMapper.update(newStock);
                }
            }
        }

        for (Dismounting businessData : businessDataList) {
            updateFlow.setGuid(businessData.getGuid().toString());
            storageMapper.updateFlow(updateFlow);
        }

        return AjaxResult.success(MessageUtils.message("module.success.issuccess"), nid);
    }

    //查询母件库存
    private StockControl getStockControl(Dismounting item) {
        StockControl newStock = new StockControl();
        Map<String, Object> params2 = new HashMap<String, Object>();
        params2.put("rkGuid", item.getRkGuid());
        params2.put("vGsBm", item.getvGsBm());
        params2.put("vHw", item.getvHw());
        params2.put("vKq", item.getvKq());
        params2.put("gDepot", item.getgDepot());
        params2.put("productcode", item.getProductID());
        newStock = stockControlMapper.findByMultiparameter(params2);
        return newStock;
    }

    //查询子件库存
    private StockControl getStockControlZj(Dismounting item) {
        StockControl newStock = new StockControl();
        Map<String, Object> params2 = new HashMap<String, Object>();
        params2.put("rkGuid", item.getRkGuid());
        params2.put("vGsBm", item.getvGsBm());
        params2.put("vHw", item.getGoodsAllocation());
        params2.put("vKq", item.getGoodsArea());
        params2.put("gDepot", item.getWarehouseAddress());
        params2.put("productcode", item.getsCode());
        newStock = stockControlMapper.findByMultiparameter(params2);
        return newStock;
    }

    // 新增库存
    private void addStockControl(Dismounting item) {
        Double cost = 0.00;
        StockControl newStock = new StockControl();
        newStock.setGuid(RandomValueUtils.getGUID());
        newStock.setProductNum(item.getActualNum());//可用数量
        newStock.setProductNumAll(item.getActualNum());//库存总数
        newStock.setRkGuid(item.getGuid());//入库标识
        newStock.setRkBid(item.getBid());//入库单号
        newStock.setIsParent("0");//是否母件
        newStock.setvHw(item.getGoodsAllocation());//入库货位
        newStock.setvKq(item.getGoodsArea());//库区
        newStock.setgDepot(item.getWarehouseAddress());//所在仓库
        newStock.setvGsBm(item.getvGsBm());//公司编码
        newStock.setvGsJc(item.getvGsJc());//公司简称
        newStock.setvGsMc(item.getvGsMc());//公司名称
        newStock.setProductCode(item.getsCode());//商品编码
        newStock.setProductName(item.getsName());
        ;//商品名称
//        newStock.setPurchasePrice(order.getPrice());//商品采购价
        newStock.setPurchasePrice(cost);//商品采购价
        newStock.setPurchaseTotalPriceAll(cost * item.getActualNum());//采购总价
        newStock.setAllotPrice(0.00);//调拨单价
        newStock.setTotalAllotPrice(0.00);//调拨总价
        newStock.setsDays(0);//库存天数
        newStock.setPurchaseStorageID(item.getBid());//采购入库单
        newStock.setPurchaseOrderID(item.getBid());//采购订单
        newStock.setPurchasePlanID(item.getBid());//采购计划单
        newStock.setdRkSj(new Date());//入库日期
        newStock.setCreateTime(new Date());//创建日期
        stockControlMapper.insert(newStock);
    }

}